package com.tangkun.environment.activity;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.tangkun.environment.R;
import com.tangkun.environment.adapter.CaptureImageAdapter;
import com.tangkun.environment.utils.LogUtils;
import com.tangkun.environment.utils.Utils;

import org.simple.eventbus.EventBus;
import org.simple.eventbus.Subscriber;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * @author tangkun
 * @ClassName: CaptureImageActivity
 * @Description: TODO(自定义相册)
 * @date 2016年4月5日 下午1:40:39
 */
public class CaptureImageActivity extends Activity {

    public static final int CAPTURE = 1;
    private static final int CAM = 2;
    private static final int CROP = 0;

    private int w, h, type;// type 0 class,1 school
    private boolean custom;
    private int resize = 1;
    private int num;

    private File path;
    private File file;

    private CaptureImageAdapter adapter;

    private ProgressDialog progressDialog;

    private List<File> targetFileList;
    private List<File> fileList;

    private static Bitmap map;

    private Cursor cursor;
    private List<String> list = new ArrayList<String>();
    /**
     * 是否是原图
     */
    private boolean isOriginalPic = false;
    /**
     * 原图控件是否展示
     */
    private boolean isShowOriginal = false;

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            progressDialog.dismiss();
            Intent intent = new Intent();
            if (fileList != null) {

                if (type == 0) {
                    EventBus.getDefault().post(fileList, "cn.com.wishcloud.child.component.CaptureImageActivity_upload");
                } else {
                    EventBus.getDefault().post(fileList, "cn.com.wishcloud.child.component.CaptureImageActivity_upload_school");
                }

            }
            intent.putExtra("fileList", (Serializable) targetFileList);
            if (targetFileList.size() > 0) {
                setResult(CAPTURE, intent);
            } else {
                // ignore
            }
            finish();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_capture);
        EventBus.getDefault().register(this);
        custom = getIntent().getBooleanExtra("custom", false);
        resize = getIntent().getIntExtra("resize", 1);
        isShowOriginal = getIntent().getBooleanExtra("isShowOriginal", false);

        String module = getIntent().getStringExtra("module");
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            path = new File(Environment.getExternalStorageDirectory() + "/environment");
        } else {
            path = new File(getExternalFilesDir(Environment.DIRECTORY_DCIM).getPath() + "/environment");
        }
        if (!path.exists()) {
            path.mkdirs();
        }
        file = new File(path, UUID.randomUUID().toString());

        w = getIntent().getIntExtra("w", 0);
        h = getIntent().getIntExtra("h", 0);
        type = getIntent().getIntExtra("type", 0);

        if (custom) {
            num = 1;
        } else {
            num = getIntent().getIntExtra("num", 1);
        }

        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("图片处理中...");

        String[] proj = {MediaStore.Images.Media.DATA};
        // take photo with date
        cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj, null, null, MediaStore.Images.Media.DATE_TAKEN + " DESC");

        // 限制图片的格式
        for (int i = 0; i < cursor.getCount(); i++) {
            cursor.moveToPosition(i);
            if (cursor.getString(0).contains("png") || cursor.getString(0).contains("jpg") || cursor.getString(0).contains("JPG") || cursor.getString(0).contains("PNG")) {
                list.add(cursor.getString(0));
            }
        }
        // 对图片顺序做逆序
        Collections.reverse(list);

        if (cursor != null) {
            cursor.close();
            cursor = null;
        }

        adapter = new CaptureImageAdapter(CaptureImageActivity.this, R.layout.list_capture_pic, num, new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO 拍照单独处理
                if (Uri.fromFile(file) == null) {
                    Toast.makeText(getApplicationContext(), "请插入内存卡", Toast.LENGTH_SHORT).show();
                    return;
                }

                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
                startActivityForResult(intent, CAM);
                Log.v("file_cam", file.getPath());
            }
        });
        GridView grid = (GridView) findViewById(R.id.capture_doc_grid);
        adapter.setList(list);
        grid.setSelection(adapter.getList().size() - 1);// 默认选中最后一项
        grid.setAdapter(adapter);

        // 滚动停止在加载图片
        grid.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                // TODO Auto-generated method stub
                switch (scrollState) {
                    case OnScrollListener.SCROLL_STATE_IDLE:// 停止滚动
                    {
                        // 设置为停止滚动
                        adapter.setScrollState(false);
                        // 当前屏幕中listview的子项的个数
                        int count = view.getChildCount();
                        Log.e("MainActivity", count + "");

                        for (int i = 0; i < count; i++) {
                            // 获取到item的头像
                            ImageView iv_show = (ImageView) view.getChildAt(i).findViewById(R.id.capture_pic);
                            if (iv_show.getTag(R.string.tag) != null && !iv_show.getTag(R.string.tag).equals("1")) {// !="1"说明需要加载数据
                                String image_url = iv_show.getTag(R.string.tag).toString();
                                // 直接从Tag中取出我们存储的数据image——url
                                iv_show.setTag(R.string.tag, "1");// 设置为已加载过数据
                                Glide.with(CaptureImageActivity.this)
                                        .load(image_url)
                                        .placeholder(R.mipmap.ic_place_holder)
                                        .dontAnimate()
                                        .into(iv_show);
                            }
                        }
                        break;
                    }
                    case OnScrollListener.SCROLL_STATE_FLING:// 滚动做出了抛的动作
                    {
                        // 设置为正在滚动
                        adapter.setScrollState(true);
                        break;
                    }

                    case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:// 正在滚动
                    {
                        // 设置为正在滚动
                        adapter.setScrollState(true);
                        break;
                    }
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                // TODO Auto-generated method stub

            }
        });

        // 预览
        ((TextView) findViewById(R.id.capture_preview)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // 跳转预览页面
                List<String> urlList = new ArrayList<String>();
                if (adapter.getSelectedList() != null) {
                    for (int i = 0; i < adapter.getSelectedList().size(); i++) {
//                        urlList.add(Uri.fromFile(adapter.getSelectedList().get(i)).toString());
                        urlList.add(adapter.getSelectedList().get(i).getPath());
                    }
                }

                Intent intent = new Intent(CaptureImageActivity.this, DeleteImageActivity.class);
                intent.putExtra("urlList", (Serializable) urlList);
                intent.putExtra("fileList", (Serializable) adapter.getSelectedList());// 增加传递文件列表过去
                intent.putExtra("index", 0);
                startActivityForResult(intent, 1000);

            }
        });
        // 完成按钮
        ((TextView) findViewById(R.id.capture_ok)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                ok();
            }
        });

        // 返回按钮
        ((ImageView) findViewById(R.id.back)).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                finish();
            }
        });

        // 取消按钮
        ((TextView) findViewById(R.id.submit)).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    private void crop(File srcFile) {
        resize(srcFile, file);
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(Uri.fromFile(file), "image/*");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", w);
        intent.putExtra("aspectY", h);
        intent.putExtra("outputX", w);
        intent.putExtra("outputY", h);
        intent.putExtra("return-data", false);
        intent.putExtra("scale", true);
        intent.putExtra("scaleUpIfNeeded", true);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        startActivityForResult(intent, CROP);
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // 相册选中的图片id集合
        if (resultCode == SelectImageActivity.RESULT_CODE_SELECT_CHANGED) {
            Set<Integer> selectedSet = new HashSet<Integer>();
            isOriginalPic = data.getBooleanExtra("isOriginalPic", false);
            selectedSet = (Set<Integer>) data.getSerializableExtra("newSelectedSet");
            adapter.setOriginalPic(isOriginalPic);
            adapter.setSelectedSet(selectedSet);
            // 如果从相册选择页面通过back键回到这个页面不用执行退出这个页面方法；点击"完成"按钮才退出当前页面
            boolean isBackClicked = data.getBooleanExtra("isBackClicked", false);
            if (!isBackClicked) {
                ok();
            } else {
                adapter.notifyDataSetChanged();
            }
        }
        // 预览列表中图片集合
        if (resultCode == DeleteImageActivity.RESULT_CODE_DELETE_CHANGED) {
            List<String> deletedList = new ArrayList<String>();
            deletedList = (List<String>) data.getSerializableExtra("newDeletedSet");
            fileList = (List<File>) data.getSerializableExtra("fileList");
            adapter.setSelectedList(deletedList);
            adapter.notifyDataSetChanged();
        }

        // 拍照
        if (resultCode == RESULT_OK) {
            switch (requestCode) {

                case CAM:
                    if (custom) {
                        crop(file);
                    } else {
                        over();
                    }
                    break;
                case CROP:
                    over();
                    break;
                default:
            }

        }

    }

    /**
     * @param srcFile 源文件
     * @param dstFile 处置后的文件 void 返回类型
     * @Description: TODO(文件处理， 在保证内存不溢出情况前提下，对图片进行角度旋转纠正，图片压缩)
     */
    private void resize(File srcFile, File dstFile) {
        Bitmap bitmap = null;
        try {
            BitmapFactory.Options opts = null;
            opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(srcFile.getPath(), opts);
            // 计算图片缩放比例
            final int minSideLength = Math.min(800, 800);
            opts.inSampleSize = computeSampleSize(opts, minSideLength, 800 * 800);
            opts.inJustDecodeBounds = false;
            opts.inInputShareable = true;
            opts.inPurgeable = true;

            try {
                bitmap = BitmapFactory.decodeFile(srcFile.getPath(), opts);
            } catch (OutOfMemoryError e) {
                bitmap = null;
                LogUtils.e("CaptureImageActivity resize()方法内存溢出了");
                return;
            }

            bitmap = reviewPicRotate(bitmap, srcFile.getPath());
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dstFile));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 85, bos);
            bos.flush();
            bos.close();
            bos = null;

        } catch (Exception e) {
            e.printStackTrace();
        } catch (OutOfMemoryError error) {
            error.printStackTrace();
        } finally {
            if (bitmap != null && !bitmap.isRecycled()) {
                bitmap.recycle();
                bitmap = null;
                System.gc();
            }
        }
    }

    /**
     * 由于Android对图片使用内存有限制，若是加载几兆的大图片便内存溢出。Bitmap会将图片的所有像素（即长x宽）加载到内存中，
     * 如果图片分辨率过大，会直接导致内存溢出（java.lang.OutOfMemoryError），
     * 只有在BitmapFactory加载图片时使用BitmapFactory.Options对相关参数进行配置来减少加载的像素。
     */
    public Bitmap getBitmapFromFile(File dst, int width, int height) {
        if (null != dst && dst.exists()) {
            BitmapFactory.Options opts = null;
            if (width > 0 && height > 0) {
                opts = new BitmapFactory.Options();
                opts.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(dst.getPath(), opts);
                // 计算图片缩放比例
                final int minSideLength = Math.min(width, height);
                opts.inSampleSize = computeSampleSize(opts, minSideLength, width * height);
                opts.inJustDecodeBounds = false;
                opts.inInputShareable = true;
                opts.inPurgeable = true;
            }
            try {
                return BitmapFactory.decodeFile(dst.getPath(), opts);
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 计算比例
     */
    public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);

        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }

        return roundedSize;
    }

    /**
     * 计算比例
     */
    private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;

        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));

        if (upperBound < lowerBound) {
            // return the larger one when there is no overlapping zone.
            return lowerBound;
        }

        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }

    /**
     * 获取图片文件的信息，是否旋转了90度，如果是则反转
     *
     * @param bitmap 需要旋转的图片
     * @param path   图片的路径
     */
    public static Bitmap reviewPicRotate(Bitmap bitmap, String path) {
        int degree = getPicRotate(path);
        if (degree != 0) {
            Matrix m = new Matrix();
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            m.setRotate(degree); // 旋转angle度
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, true);// 从新生成图片
        }
        return bitmap;
    }

    /**
     * 读取图片文件旋转的角度
     *
     * @param path 图片绝对路径
     * @return 图片旋转的角度
     */
    public static int getPicRotate(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 图片变焦
     */
    public static Bitmap zoomImg(Bitmap bm, int newWidth, int newHeight) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        map = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
        return map;
    }

    public void ok() {
        fileList = adapter.getSelectedList();
        if (custom) {
            if (fileList.size() > 0) {
                crop(fileList.get(0));
            }
        } else {
            // progressDialog.show();
            new Thread(new Runnable() {

                @Override
                public void run() {
                    targetFileList = new ArrayList<File>();
                    if (fileList.size() > 0) {
                        for (File f : fileList) {
                            if (isOriginalPic) {
                                targetFileList.add(f);
                            } else {
                                try {
                                    System.out.println("ok()方法中file大小：" + Utils.getImgFileSizes(f));
                                } catch (Exception e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                                File file = new File(path, UUID.randomUUID().toString());
                                resize(f, file);
                                if (file.length() > 0) {
                                    targetFileList.add(file);
                                }
                                try {
                                    System.out.println("ok()方法中压缩后file大小：" + Utils.getImgFileSizes(file));
                                } catch (Exception e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                    handler.obtainMessage().sendToTarget();
                }
            }).start();
        }

    }

    private void over() {

        progressDialog.show();
        new Thread(new Runnable() {

            @Override
            public void run() {
                targetFileList = new ArrayList<File>();
                File fileNow = new File(path, UUID.randomUUID().toString());
                Log.v("file_over", file.getPath());
                try {
                    System.out.println("over()方法中压缩前file大小：" + Utils.getImgFileSizes(file));
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                resize(file, fileNow);
                try {
                    System.out.println("over()方法中压缩后file大小：" + Utils.getImgFileSizes(fileNow));
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (fileNow.length() > 0) {
                    targetFileList.add(fileNow);
                }

                for (int i = 0; i < targetFileList.size(); i++) {
                    Log.v("file", targetFileList.get(i).getPath());
                }

                if (targetFileList.size() > 0) {
                    handler.obtainMessage().sendToTarget();
                } else {
                    // 不能再子线程里更新UI,需放在主线程里，否则会报错,这就是导致点击拍照那个应用无响应的原因
                    runOnUiThread(new Runnable() {
                        public void run() {
                            progressDialog.dismiss();
                            Toast.makeText(CaptureImageActivity.this, "获取图片路径失败,请重试", Toast.LENGTH_SHORT).show();
                        }
                    });
                }

            }
        }).start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        if (map != null && !map.isRecycled()) {
            map.recycle();
            map = null;
        }
    }

    @Subscriber(tag = "cn.com.wishcloud.child.component.broadcast_refresh_btn_state")
    public void refreshBroadCast(boolean b) {
        // 有选中图片时显示选中图片数量，且预览按钮可点击；否则不现实图片数量，且预览按钮不可点击
        if (adapter.getSelectedList().size() > 0) {
            ((TextView) findViewById(R.id.capture_selected_num)).setVisibility(View.VISIBLE);
            ((TextView) findViewById(R.id.capture_selected_num)).setText("" + adapter.getSelectedList().size());
        } else {
            ((TextView) findViewById(R.id.capture_selected_num)).setVisibility(View.GONE);
            ((TextView) findViewById(R.id.capture_selected_num)).setText("" + adapter.getSelectedList().size());
        }
        if (b) {
            ((TextView) findViewById(R.id.capture_preview)).setEnabled(true);
            ((TextView) findViewById(R.id.capture_preview)).setTextColor(getResources().getColor(R.color.black));
        } else {
            ((TextView) findViewById(R.id.capture_preview)).setEnabled(false);
            ((TextView) findViewById(R.id.capture_preview)).setTextColor(getResources().getColor(R.color.gray));
        }
    }
}
